const Binance = require('node-binance-api');
require('dotenv').config();

// 配置Binance客户端
const binanceOptions = {
  APIKEY: process.env.BINANCE_API_KEY,
  APISECRET: process.env.BINANCE_SECRET_KEY,
  test: process.env.BINANCE_DEMO_TRADING === 'true', // 使用模拟交易模式
  useServerTime: false, // 初始化时禁用，避免立即网络请求
  recvWindow: 60000,
  verbose: false,
  family: 4,
  timeout: 30000,
  reconnect: false, // 禁用自动重连
  hedgeMode: true, // 启用对冲模式，支持同时持有多空仓位
  log: (log) => {
    // 减少日志输出
  },
};

// 添加代理配置
if (process.env.USE_PROXY === 'true') {
  const proxyUrl = `http://${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;
  console.log(`🌐 使用代理: ${proxyUrl}`);
  binanceOptions.httpsProxy = proxyUrl;
}

const binance = new Binance(binanceOptions);

// 测试配置
const TRADING_SYMBOL = process.env.TRADING_SYMBOL || 'ETHUSDT';
const TEST_QUANTITY = 0.006; // 测试数量（ETH）- 约25 USDT，满足最小订单要求
const LEVERAGE = 5; // 杠杆倍数

class TradingTester {
  constructor() {
    this.logger = console;
    this.currentOrderId = null;
    this.currentPosition = null;
  }

  // 测试网络连接
  async testConnection(retries = 3) {
    for (let i = 0; i < retries; i++) {
      try {
        this.logger.log(`🔗 测试网络连接... (尝试 ${i + 1}/${retries})`);
        
        // 先测试简单的ping
        const serverTime = await binance.futuresTime();
        this.logger.log(`✅ 网络连接正常，服务器时间: ${new Date(serverTime.serverTime)}`);
        
        // 启用服务器时间同步
        binance.options.useServerTime = true;
        
        // 检查并启用对冲模式
        await this.ensureHedgeMode();
        
        return true;
      } catch (error) {
        this.logger.error(`❌ 连接尝试 ${i + 1} 失败: ${error.message}`);
        
        if (i === retries - 1) {
          this.logger.log('💡 网络连接失败，可能的原因：');
          this.logger.log('   1. 网络连接问题');
          this.logger.log('   2. 代理设置错误');
          this.logger.log('   3. Binance API服务不可用');
          this.logger.log('   4. 防火墙阻止连接');
          
          if (process.env.USE_PROXY === 'true') {
            this.logger.log(`   当前代理: ${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`);
            this.logger.log('   请确认代理服务正在运行');
          } else {
            this.logger.log('   建议启用代理访问Binance API');
          }
          
          return false;
        }
        
        // 等待2秒后重试
        await new Promise(resolve => setTimeout(resolve, 2000));
      }
    }
    return false;
  }

  // 检查并启用对冲模式
  async ensureHedgeMode() {
    try {
      // 检查当前对冲模式状态
      this.logger.log('🔍 检查对冲模式状态...');
      const positionMode = await binance.futuresPositionSideDual();
      
      this.logger.log(`📋 当前对冲模式状态: ${positionMode.dualSidePosition ? '已启用' : '未启用'}`);
      
      if (!positionMode.dualSidePosition) {
        this.logger.log('⚙️ 启用对冲模式...');
        const result = await binance.futuresChangePositionSideDual(true);
        this.logger.log('✅ 对冲模式启用成功:', result);
      } else {
        this.logger.log('✅ 对冲模式已启用');
      }
    } catch (error) {
      this.logger.error('❌ 对冲模式设置失败:', error.message);
      // 如果是因为有持仓而无法切换，给出提示
      if (error.message.includes('Position side does not match user\'s setting') || 
          error.message.includes('Unable to change position mode')) {
        this.logger.log('💡 提示: 可能因为有持仓而无法切换对冲模式，请先平仓后重试');
      }
      throw error;
    }
  }

  // 获取当前价格
  async getCurrentPrice(symbol = TRADING_SYMBOL) {
    try {
      const prices = await binance.futuresPrices();
      const price = parseFloat(prices[symbol]);
      this.logger.log(`📊 ${symbol} 当前价格: $${price}`);
      return price;
    } catch (error) {
      this.logger.error('获取价格失败:', error.message);
      throw error;
    }
  }

  // 获取账户信息
  async getAccountInfo() {
    try {
      const account = await binance.futuresAccount();
      const balance = account.assets.find(asset => asset.asset === 'USDT');
      this.logger.log(`💰 账户余额: ${balance.walletBalance} USDT`);
      this.logger.log(`💰 可用余额: ${balance.availableBalance} USDT`);
      return account;
    } catch (error) {
      this.logger.error('获取账户信息失败:', error.message);
      throw error;
    }
  }

  // 获取持仓信息
  async getPositions(symbol = TRADING_SYMBOL) {
    try {
      const positions = await binance.futuresPositionRisk();
      const position = positions.find(pos => pos.symbol === symbol);
      
      if (position && parseFloat(position.positionAmt) !== 0) {
        this.logger.log(`📈 持仓信息:`);
        this.logger.log(`   符号: ${position.symbol}`);
        this.logger.log(`   数量: ${position.positionAmt}`);
        this.logger.log(`   开仓价: $${position.entryPrice}`);
        this.logger.log(`   标记价: $${position.markPrice}`);
        this.logger.log(`   未实现盈亏: $${position.unRealizedProfit}`);
        this.logger.log(`   杠杆: ${position.leverage}x`);
        this.currentPosition = position;
        return position;
      } else {
        this.logger.log(`📈 ${symbol} 无持仓`);
        this.currentPosition = null;
        return null;
      }
    } catch (error) {
      this.logger.error('获取持仓信息失败:', error.message);
      throw error;
    }
  }



  // 设置杠杆
  async setLeverage(symbol = TRADING_SYMBOL, leverage = LEVERAGE) {
    try {
      this.logger.log(`⚙️ 设置杠杆: ${symbol} - ${leverage}x`);
      const result = await binance.futuresLeverage(symbol, leverage);
      this.logger.log(`✅ 杠杆设置成功: ${JSON.stringify(result)}`);
      return result;
    } catch (error) {
      this.logger.error(`❌ 杠杆设置失败: ${error.message}`);
      // 如果杠杆设置失败，继续执行（可能已经是目标杠杆）
      return null;
    }
  }

  // 开多仓（市价买入）
  async openLongPosition(symbol = TRADING_SYMBOL, quantity = TEST_QUANTITY) {
    try {
      this.logger.log(`🚀 开多仓: ${symbol} 数量: ${quantity}`);
      
      // 设置杠杆
      await this.setLeverage(symbol, LEVERAGE);
      
      // 市价买入
      const order = await binance.futuresMarketBuy(symbol, quantity, { 
        newOrderRespType: 'RESULT',
        positionSide: 'LONG' // 双向持仓模式下的多仓
      });
      
      this.currentOrderId = order.orderId;
      this.logger.log(`✅ 开多仓成功:`);
      this.logger.log(`   订单ID: ${order.orderId}`);
      this.logger.log(`   成交数量: ${order.executedQty}`);
      this.logger.log(`   平均价格: $${order.avgPrice || '待确认'}`);
      this.logger.log(`   订单状态: ${order.status}`);
      
      return order;
    } catch (error) {
      this.logger.error(`❌ 开多仓失败: ${error.message}`);
      throw error;
    }
  }

  // 开空仓（市价卖出）
  async openShortPosition(symbol = TRADING_SYMBOL, quantity = TEST_QUANTITY) {
    try {
      this.logger.log(`📉 开空仓: ${symbol} 数量: ${quantity}`);
      
      // 设置杠杆
      await this.setLeverage(symbol, LEVERAGE);
      
      // 市价卖出
      const order = await binance.futuresMarketSell(symbol, quantity, { 
        newOrderRespType: 'RESULT',
        positionSide: 'SHORT' // 双向持仓模式下的空仓
      });
      
      this.currentOrderId = order.orderId;
      this.logger.log(`✅ 开空仓成功:`);
      this.logger.log(`   订单ID: ${order.orderId}`);
      this.logger.log(`   成交数量: ${order.executedQty}`);
      this.logger.log(`   平均价格: $${order.avgPrice || '待确认'}`);
      this.logger.log(`   订单状态: ${order.status}`);
      
      return order;
    } catch (error) {
      this.logger.error(`❌ 开空仓失败: ${error.message}`);
      throw error;
    }
  }

  // 平仓
  async closePosition(symbol = TRADING_SYMBOL) {
    try {
      const position = await this.getPositions(symbol);
      
      if (!position || parseFloat(position.positionAmt) === 0) {
        this.logger.log(`❌ 没有${symbol}持仓需要平仓`);
        return null;
      }

      const positionAmt = parseFloat(position.positionAmt);
      const quantity = Math.abs(positionAmt);
      const side = positionAmt > 0 ? 'SELL' : 'BUY'; // 多仓平仓用卖，空仓平仓用买
      const positionSide = positionAmt > 0 ? 'LONG' : 'SHORT'; // 持仓方向

      this.logger.log(`🔄 平仓: ${symbol} 数量: ${quantity} 方向: ${side} 持仓方向: ${positionSide}`);

      let order;
      if (side === 'SELL') {
        order = await binance.futuresMarketSell(symbol, quantity, { 
          newOrderRespType: 'RESULT',
          positionSide: positionSide
        });
      } else {
        order = await binance.futuresMarketBuy(symbol, quantity, { 
          newOrderRespType: 'RESULT',
          positionSide: positionSide
        });
      }

      this.logger.log(`✅ 平仓成功:`);
      this.logger.log(`   订单ID: ${order.orderId}`);
      this.logger.log(`   成交数量: ${order.executedQty}`);
      this.logger.log(`   平均价格: $${order.avgPrice || '待确认'}`);
      this.logger.log(`   订单状态: ${order.status}`);

      return order;
    } catch (error) {
      this.logger.error(`❌ 平仓失败: ${error.message}`);
      throw error;
    }
  }

  // 设置止损单
  async setStopLoss(symbol = TRADING_SYMBOL, stopPrice, quantity) {
    try {
      const position = await this.getPositions(symbol);
      
      if (!position || parseFloat(position.positionAmt) === 0) {
        this.logger.log(`❌ 没有${symbol}持仓，无法设置止损`);
        return null;
      }

      const positionAmt = parseFloat(position.positionAmt);
      const side = positionAmt > 0 ? 'SELL' : 'BUY'; // 止损方向：多仓止损用SELL，空仓止损用BUY
      const positionSide = positionAmt > 0 ? 'LONG' : 'SHORT'; // 持仓方向
      const qty = quantity || Math.abs(positionAmt);

      this.logger.log(`🛡️ 设置止损: ${symbol} 止损价: $${stopPrice} 数量: ${qty} 方向: ${side} 持仓方向: ${positionSide}`);

      // 在对冲模式下，STOP_MARKET订单的正确参数组合：
      // 1. 不能同时使用closePosition=true和positionSide
      // 2. 使用quantity和positionSide的组合
      // 3. 多头持仓：side=SELL, positionSide=LONG
      // 4. 空头持仓：side=BUY, positionSide=SHORT
      let order;
      if (positionAmt > 0) {
        // 多仓止损：type, side, symbol, quantity, price, params
        order = await binance.futuresOrder('STOP_MARKET', 'SELL', symbol, qty, false, {
          stopPrice: stopPrice,
          positionSide: 'LONG'
        });
      } else {
        // 空仓止损：type, side, symbol, quantity, price, params
        order = await binance.futuresOrder('STOP_MARKET', 'BUY', symbol, Math.abs(qty), false, {
          stopPrice: stopPrice,
          positionSide: 'SHORT'
        });
      }

      this.logger.log(`✅ 止损单设置成功:`);
      this.logger.log(`   订单ID: ${order.orderId}`);
      this.logger.log(`   止损价格: $${stopPrice}`);
      this.logger.log(`   订单状态: ${order.status}`);

      return order;
    } catch (error) {
      this.logger.error(`❌ 设置止损失败: ${error.message}`);
      throw error;
    }
  }

  // 设置止盈单
  async setTakeProfit(symbol = TRADING_SYMBOL, takeProfitPrice, quantity) {
    try {
      const position = await this.getPositions(symbol);
      
      if (!position || parseFloat(position.positionAmt) === 0) {
        this.logger.log(`❌ 没有${symbol}持仓，无法设置止盈`);
        return null;
      }

      const positionAmt = parseFloat(position.positionAmt);
      const side = positionAmt > 0 ? 'SELL' : 'BUY'; // 期货止盈单方向：多仓用SELL，空仓用BUY
      const positionSide = positionAmt > 0 ? 'LONG' : 'SHORT'; // 持仓方向
      const qty = quantity || Math.abs(positionAmt);

      this.logger.log(`🎯 设置止盈: ${symbol} 止盈价: $${takeProfitPrice} 数量: ${qty} 方向: ${side} 持仓方向: ${positionSide}`);

      // 在对冲模式下，TAKE_PROFIT_MARKET订单的正确参数组合：
      // 1. 不能同时使用closePosition=true和positionSide
      // 2. 使用quantity和positionSide的组合
      // 3. 多头持仓：side=SELL, positionSide=LONG
      // 4. 空头持仓：side=BUY, positionSide=SHORT
      let order;
      if (positionAmt > 0) {
        // 多仓止盈：type, side, symbol, quantity, price, params
        order = await binance.futuresOrder('TAKE_PROFIT_MARKET', 'SELL', symbol, qty, false, {
          stopPrice: takeProfitPrice,
          positionSide: 'LONG'
        });
      } else {
        // 空仓止盈：type, side, symbol, quantity, price, params
        order = await binance.futuresOrder('TAKE_PROFIT_MARKET', 'BUY', symbol, Math.abs(qty), false, {
          stopPrice: takeProfitPrice,
          positionSide: 'SHORT'
        });
      }

      this.logger.log(`✅ 止盈单设置成功:`);
      this.logger.log(`   订单ID: ${order.orderId}`);
      this.logger.log(`   止盈价格: $${takeProfitPrice}`);
      this.logger.log(`   订单状态: ${order.status}`);

      return order;
    } catch (error) {
      this.logger.error(`❌ 设置止盈失败: ${error.message}`);
      throw error;
    }
  }

  // 获取所有挂单
  async getOpenOrders(symbol = TRADING_SYMBOL) {
    try {
      const orders = await binance.futuresOpenOrders(symbol);
      
      if (orders.length > 0) {
        this.logger.log(`📋 ${symbol} 挂单列表:`);
        orders.forEach(order => {
          this.logger.log(`   订单ID: ${order.orderId} | 类型: ${order.type} | 方向: ${order.side} | 数量: ${order.origQty} | 价格: $${order.price || order.stopPrice}`);
        });
      } else {
        this.logger.log(`📋 ${symbol} 无挂单`);
      }
      
      return orders;
    } catch (error) {
      this.logger.error('获取挂单失败:', error.message);
      throw error;
    }
  }

  // 取消所有挂单
  async cancelAllOrders(symbol = TRADING_SYMBOL) {
    try {
      this.logger.log(`🗑️ 取消${symbol}所有挂单`);
      const result = await binance.futuresCancelAll(symbol);
      this.logger.log(`✅ 已取消所有挂单: ${JSON.stringify(result)}`);
      return result;
    } catch (error) {
      this.logger.error(`❌ 取消挂单失败: ${error.message}`);
      throw error;
    }
  }

  // 完整的交易测试流程
  async runFullTradingTest() {
    try {
      this.logger.log('🚀 开始完整交易测试...\n');

      // 1. 获取初始状态
      this.logger.log('=== 1. 获取初始状态 ===');
      await this.getAccountInfo();
      await this.getCurrentPrice();
      await this.getPositions();
      await this.getOpenOrders();
      
      // 2. 清理现有挂单
      this.logger.log('\n=== 2. 清理现有挂单 ===');
      await this.cancelAllOrders();

      // 3. 开多仓测试
      this.logger.log('\n=== 3. 开多仓测试 ===');
      const currentPrice = await this.getCurrentPrice();
      await this.openLongPosition();
      
      // 等待一秒让订单确认
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      // 4. 检查持仓
      this.logger.log('\n=== 4. 检查持仓 ===');
      const position = await this.getPositions();
      
      if (position) {
        // 5. 设置止损止盈
        this.logger.log('\n=== 5. 设置止损止盈 ===');
        const entryPrice = parseFloat(position.entryPrice);
        const stopLossPrice = entryPrice * 0.98; // 2%止损
        const takeProfitPrice = entryPrice * 1.04; // 4%止盈
        
        await this.setStopLoss(TRADING_SYMBOL, stopLossPrice);
        await this.setTakeProfit(TRADING_SYMBOL, takeProfitPrice);
        
        // 6. 查看挂单状态
        this.logger.log('\n=== 6. 查看挂单状态 ===');
        await this.getOpenOrders();
        
        // 7. 等待几秒观察
        this.logger.log('\n=== 7. 等待观察（5秒）===');
        await new Promise(resolve => setTimeout(resolve, 5000));
        
        // 8. 平仓
        this.logger.log('\n=== 8. 平仓测试 ===');
        await this.closePosition();
        
        // 9. 清理剩余挂单
        this.logger.log('\n=== 9. 清理剩余挂单 ===');
        await this.cancelAllOrders();
      }

      // 10. 最终状态检查
      this.logger.log('\n=== 10. 最终状态检查 ===');
      await this.getPositions();
      await this.getOpenOrders();
      await this.getAccountInfo();

      this.logger.log('\n✅ 完整交易测试完成！');

    } catch (error) {
      this.logger.error('\n❌ 交易测试失败:', error.message);
      
      // 紧急清理
      try {
        this.logger.log('\n🚨 执行紧急清理...');
        await this.cancelAllOrders();
        await this.closePosition();
      } catch (cleanupError) {
        this.logger.error('紧急清理失败:', cleanupError.message);
      }
    }
  }

  // 测试止损止盈功能
  async runStopLossTakeProfitTest() {
    try {
      this.logger.log('🚀 开始止损止盈测试...\n');

      // 先测试网络连接
      const connected = await this.testConnection();
      if (!connected) {
        this.logger.log('❌ 网络连接失败，无法继续测试');
        return;
      }

      // 获取当前状态
      await this.getAccountInfo();
      const currentPrice = await this.getCurrentPrice();
      await this.getPositions();

      // 开多仓
      this.logger.log('\n=== 开多仓 ===');
      await this.openLongPosition();
      
      // 等待确认
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      // 检查持仓
      const position = await this.getPositions();
      
      if (position) {
        // 设置止损止盈
        this.logger.log('\n=== 设置止损止盈 ===');
        const entryPrice = parseFloat(position.entryPrice);
        const stopLossPrice = (entryPrice * 0.98).toFixed(2); // 2%止损
        const takeProfitPrice = (entryPrice * 1.04).toFixed(2); // 4%止盈
        
        this.logger.log(`📊 开仓价格: $${entryPrice}`);
        this.logger.log(`🛡️ 止损价格: $${stopLossPrice} (-2%)`);
        this.logger.log(`🎯 止盈价格: $${takeProfitPrice} (+4%)`);
        
        await this.setStopLoss(TRADING_SYMBOL, stopLossPrice);
        await this.setTakeProfit(TRADING_SYMBOL, takeProfitPrice);
        
        // 查看挂单状态
        this.logger.log('\n=== 查看挂单状态 ===');
        await this.getOpenOrders();
        
        // 等待几秒观察
        this.logger.log('\n=== 等待观察（10秒）===');
        await new Promise(resolve => setTimeout(resolve, 10000));
        
        // 取消挂单并平仓
        this.logger.log('\n=== 清理测试 ===');
        await this.cancelAllOrders();
        await this.closePosition();
      }

      // 最终状态检查
      this.logger.log('\n=== 最终状态检查 ===');
      await this.getPositions();
      await this.getOpenOrders();

      this.logger.log('\n✅ 止损止盈测试完成！');

    } catch (error) {
      this.logger.error('\n❌ 止损止盈测试失败:', error.message);
      
      // 紧急清理
      try {
        this.logger.log('\n🚨 执行紧急清理...');
        await this.cancelAllOrders();
        await this.closePosition();
      } catch (cleanupError) {
        this.logger.error('紧急清理失败:', cleanupError.message);
      }
    }
  }

  // 简单的开仓平仓测试
  async runSimpleTest() {
    try {
      this.logger.log('🚀 开始简单交易测试...\n');

      // 先测试网络连接
      const connected = await this.testConnection();
      if (!connected) {
        this.logger.log('❌ 网络连接失败，无法继续测试');
        return;
      }

      // 获取当前状态
      await this.getAccountInfo();
      await this.getCurrentPrice();
      await this.getPositions();

      // 开多仓
      this.logger.log('\n=== 开多仓 ===');
      await this.openLongPosition();
      
      // 等待确认
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      // 检查持仓
      await this.getPositions();
      
      // 平仓
      this.logger.log('\n=== 平仓 ===');
      await this.closePosition();
      
      // 最终检查
      await this.getPositions();

      this.logger.log('\n✅ 简单交易测试完成！');

    } catch (error) {
      this.logger.error('\n❌ 简单测试失败:', error.message);
    }
  }
}

// 主函数
async function main() {
  const tester = new TradingTester();
  
  console.log('🔧 交易测试工具');
  console.log('📊 交易对:', TRADING_SYMBOL);
  console.log('💰 测试数量:', TEST_QUANTITY);
  console.log('⚡ 杠杆倍数:', LEVERAGE);
  console.log('🎯 模拟交易:', process.env.BINANCE_DEMO_TRADING === 'true' ? '是' : '否');
  console.log('=====================================\n');

  // 选择测试类型
  const testType = process.argv[2] || 'simple';
  
  if (testType === 'full') {
    await tester.runFullTradingTest();
  } else if (testType === 'stoploss') {
    await tester.runStopLossTakeProfitTest();
  } else {
    await tester.runSimpleTest();
  }
}

// 运行测试
if (require.main === module) {
  main().catch(console.error);
}

module.exports = TradingTester;